package org.juiceshop.gm;

import org.codehaus.groovy.runtime.GroovyCategorySupport;

import groovy.lang.Closure;

public class MusicObjectCategory {

	
    private static ThreadLocal<Boolean> __inUse = new ThreadLocal<Boolean>() {
        @Override
		protected synchronized Boolean initialValue() {
            return false;
        }
    };

	/**
	 * Use this class as a Groovy category for given closure.
	 * If we are already in <code>VirtualMethods</code> scope,
	 * the closure is simply called.
	 * This state is controlled by a <code>ThreadLocal</code> variable.
	 * @param closure Closure to execute in the scope of the category.
	 * @return Closure return value.
	 */
	public static Object use (Closure closure) {
		if (__inUse.get()) return closure.call();
		__inUse.set(true);
		try {
			return GroovyCategorySupport.use(MusicObjectCategory.class, closure);
		} finally {
			__inUse.set(false);
		}
	}

	
	
	private MusicObjectCategory() {}
	
	public static Phrase multiply (Integer self, Note note ) {
		Phrase phr = new Phrase (note);
		for (int i=1; i<self; i++) {
			phr.append(note);
		}
		return phr;
	}
	
	public static Phrase multiply (Integer self, Phrase phrase) {
		Phrase phr = phrase.copy();
		for (int i=1; i<self; i++) {
			phr.append(phrase);
		}
		return phr;
	}
	
	public static Phrase multiply (Integer self, Chord chord ) {
		Phrase phr = new Phrase (chord);
		for (int i=1; i<self; i++) {
			phr.append(chord);
		}
		return phr;
	}
	
}
